package org.jetnuke.modules.pictures;

import java.awt.image.FilteredImageSource;
import java.awt.image.ImageFilter;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.GregorianCalendar;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.jforum.ActionServletRequest;
import net.jforum.JForumExecutionContext;
import net.jforum.util.legacy.commons.fileupload.FileItem;
import net.jforum.util.preferences.ConfigKeys;
import net.jforum.util.preferences.SystemGlobals;

import org.apache.velocity.VelocityContext;
import org.jetnuke.common.ActionForward;
import org.jetnuke.common.IAction;
import org.jetnuke.common.IAdminInfo;
import org.jetnuke.common.IModuleInfo;
import org.jetnuke.common.IUserInfo;
import org.jetnuke.dao.DataAccessDriver;
import org.jetnuke.dao.PictureDAO;
import org.jetnuke.entities.Picture;
import org.jetnuke.servlets.utilities.StringUtils;
import org.jetnuke.util.JetUtil;

import com.sun.jimi.core.InvalidOptionException;
import com.sun.jimi.core.Jimi;
import com.sun.jimi.core.JimiException;
import com.sun.jimi.core.JimiImage;
import com.sun.jimi.core.encoder.jpg.JPGEncoder;
import com.sun.jimi.core.encoder.jpg.JPGEncoderFactory;
import com.sun.jimi.core.filters.AspectReplicateScaleFilter;
import com.sun.jimi.core.filters.Smooth;
import com.sun.jimi.core.raster.JimiRasterImage;

public class UploadFiles implements IAction {
	
	
	public ActionForward exec(HttpServletRequest request,
			HttpServletResponse response, VelocityContext vc, IModuleInfo info,
			String op, IUserInfo ui, IAdminInfo ai) throws Exception {
		
		
		if(ui==null || ui.getID()<2)
			return null;
		String ip=request.getRemoteAddr();
		String initPath=SystemGlobals.getValue(ConfigKeys.ATTACHMENTS_STORE_DIR) + "/pictures/"+ui.getID()+"/";
		//String path = sc.getRealPath(initPath);
		File pathDir=new File(initPath);
		if(!pathDir.exists()){
			pathDir.mkdirs();
		}
		
		
		//JForum.DataHolder dataHolder = (JForum.DataHolder)JForumBaseServlet.localData.get();
		ActionServletRequest asr=JForumExecutionContext.getRequest();
		int album=Integer.parseInt(asr.getParameter("album"));
		FileItem file1=(FileItem)asr.getObjectParameter("file1");
		FileItem file2=(FileItem)asr.getObjectParameter("file2");
		FileItem file3=(FileItem)asr.getObjectParameter("file3");
		FileItem file4=(FileItem)asr.getObjectParameter("file4");
		FileItem file5=(FileItem)asr.getObjectParameter("file5");
		if(file1!=null){
			manageFile(file1,pathDir,ui,ip,album);
		}
		if(file2!=null){
			manageFile(file2,pathDir,ui,ip,album);
		}
		if(file3!=null){
			manageFile(file3,pathDir,ui,ip,album);
		}
		if(file4!=null){
			manageFile(file4,pathDir,ui,ip,album);
		}
		if(file5!=null){
			manageFile(file5,pathDir,ui,ip,album);
		}

		
		JetUtil.redirect(vc,response,request.getContextPath()+"/do/pictures/show_album?aid="+album);
		return null;
	}
	private void manageFile(FileItem ff,File pathDir,IUserInfo ui, String ip,int album)throws Exception{
		//long fileSize=ff.getSize();
		//long resourcesSize=getResourcesSize(0,pathDir);

				
		String realName = ff.getName();
		String simplifiedName=StringUtils.getSimpleFileName(realName);
		if(simplifiedName.toLowerCase().endsWith(".zip")){
			ZipInputStream in = new ZipInputStream(ff.getInputStream());
			ZipEntry entry=null;
			
			while((entry=in.getNextEntry())!=null){
				ByteArrayOutputStream baosEntry=new ByteArrayOutputStream((int)entry.getSize());
				byte[] buf = new byte[2048];
		        int len=0;
		        while ((len = in.read(buf)) > 0) {
		        	baosEntry.write(buf, 0, len);
		        }
		  
		        baosEntry.close();
		        if(baosEntry.size()>0){
			        try{
			        	JimiRasterImage img=Jimi.getRasterImage(new ByteArrayInputStream(baosEntry.toByteArray()),Jimi.SYNCHRONOUS|Jimi.VIRTUAL_MEMORY);
			        	
			        	manageImage(pathDir, ui, ip, StringUtils.getSimpleFileName(entry.getName()), baosEntry.size(),  img,baosEntry,album);
			        	
						
			        }catch(Throwable t){
			        	t.printStackTrace();
			        }
		        }
		        
			}
			in.close();
		}else{
			
			int size=(int)ff.getSize();
			
			ByteArrayOutputStream baos=new ByteArrayOutputStream(size);
			baos.write(ff.get());
			JimiRasterImage img=Jimi.getRasterImage(new ByteArrayInputStream(baos.toByteArray()),Jimi.SYNCHRONOUS);
			manageImage(pathDir, ui, ip, simplifiedName, size, img,baos,album);
			
		}
		
		
		
		
		
		
		
	}
	private void manageImage(File pathDir, IUserInfo ui, String ip, String simplifiedName, int size,  JimiRasterImage img, ByteArrayOutputStream baos,int album) throws FileNotFoundException, IOException, JimiException, InvalidOptionException, Exception {
		String mimeType="";
		
		String extension = simplifiedName.toLowerCase();
		String name_no_extension=extension;
		int last=extension.lastIndexOf(".");
		if (last != -1) {
			extension = extension.substring(last + 1);
			name_no_extension=name_no_extension.substring(0,last);
		}
		mimeType= decodeMimeType(extension);
		
		int total_size=size;
		int height=img.getHeight();
		int width=img.getWidth();
		int max=Math.max(height, width);
		File f = new File(pathDir,simplifiedName);
		OutputStream outputStream = new BufferedOutputStream(new FileOutputStream(f));
		baos.writeTo(outputStream);
		outputStream.flush();
		outputStream.close();
		Picture picture=new Picture();
		picture.setTITLE(name_no_extension);
		if(max>100){
		
			ImageFilter smoothedFilter =	 new Smooth(img.getImageProducer(), 1); 
			
			FilteredImageSource smoothedSource =  new FilteredImageSource(img.getImageProducer(), smoothedFilter); 
			ImageFilter scaleFilter =	 new AspectReplicateScaleFilter(width*100/max,height*100/max );
			FilteredImageSource scaledSource =  new FilteredImageSource(smoothedSource, scaleFilter);
			JimiImage scaledImage = Jimi.createRasterImage(scaledSource);
			
			int extIndex=  simplifiedName.lastIndexOf(".");
			String thumbName="thumb_";
			if(extIndex>-1){
				thumbName+= simplifiedName.substring(0,extIndex);
			}else{
				thumbName+= simplifiedName;
			}
			thumbName=thumbName+".jpg";
			JPGEncoderFactory factory = new JPGEncoderFactory();
			JPGEncoder encoder = (JPGEncoder) factory.createEncoder();
			encoder.setProperty("quality", new Integer(70));
			File fthumb = new File(pathDir,thumbName);
			BufferedOutputStream out=new BufferedOutputStream(new FileOutputStream(fthumb));
			encoder.encodeImage(scaledImage, out); 
			out.close();	
			total_size=total_size+(int)fthumb.length();
			picture.setTHUMBNAME(thumbName);
			picture.setTHUMBMIMETYPE("image/jpeg");
		}
		if(max>400){
			ImageFilter smoothedFilter =	 new Smooth(img.getImageProducer(), 1); 
			
			FilteredImageSource smoothedSource =  new FilteredImageSource(img.getImageProducer(), smoothedFilter); 
			ImageFilter scaleFilter =	 new AspectReplicateScaleFilter(height*400/max, width*400/max);
			FilteredImageSource scaledSource =  new FilteredImageSource(smoothedSource, scaleFilter);
			JimiImage scaledImage = Jimi.createRasterImage(scaledSource);
			
			int extIndex=  simplifiedName.lastIndexOf(".");
			String mediumName="medium_";
			if(extIndex>-1){
				mediumName+= simplifiedName.substring(0,extIndex);
			}else{
				mediumName+= simplifiedName;
			}
			mediumName=mediumName+".jpg";
			JPGEncoderFactory factory = new JPGEncoderFactory();
			JPGEncoder encoder = (JPGEncoder) factory.createEncoder();
			encoder.setProperty("quality", new Integer(70));
			File fmedium = new File(pathDir,mediumName);
			BufferedOutputStream out=new BufferedOutputStream(new FileOutputStream(fmedium));
			encoder.encodeImage(scaledImage, out); 
			out.close();	
			total_size=total_size+(int)fmedium.length();
			picture.setMEDIUMNAME(mediumName);
			picture.setMEDIUMMIMETYPE("image/jpeg");
		}
		
		PictureDAO pd=DataAccessDriver.getInst().newPictureDAO();
		
		picture.setUID(ui.getID());
		picture.setAPPROVED("YES");
		picture.setCAPTION("");
		picture.setFILENAME(simplifiedName);
		picture.setFILEPATH("");
		picture.setFILESIZE(size);
		picture.setKEYWORDS("");
		picture.setMTIME(new GregorianCalendar().getTime());
		picture.setPHEIGHT(height);
		picture.setPIC_RAW_IP(ip);
		picture.setPWIDTH(width);
		
		picture.setTOTAL_SIZE(total_size);
		picture.setMIMETYPE(mimeType);
		picture.setAID(album);
		pd.addNew(picture);
	}

	private String decodeMimeType(String ext) {
		if("bmp".equals(ext))
			return "image/bmp";
		if("gif".equals(ext))
			return "image/gif";
		if("jpe".equals(ext)|| "jpg".equals(ext)||"jpeg".equals(ext))
			return "image/jpeg";
		if("png".equals(ext))
			return "image/png";
		if("tif".equals(ext)||"tiff".equals(ext))
			return "image/tiff";
		if("ico".equals(ext))
			return "image/x-icon";
		return "";
	}
	public static  long getResourcesSize(long initSize,File pathDir) {
		File f[]=pathDir.listFiles();
		long ret=initSize;
		for(int i=0;i<f.length;i++){
			if(f[i].isFile()){
				ret=ret+f[i].length();
			}else{
				ret=getResourcesSize(ret,f[i]);
			}
		}
		return ret;
	}

}
